package hello

import (
	"appengine"
	"appengine/datastore"
)

type Category struct {
	Id int64
	Name string
	Code string
}

func createCategoryKey(c *appengine.Context) *datastore.Key {
	return datastore.NewIncompleteKey(*c, "Category", nil)
}

func restoreCategoryKey(c *appengine.Context, id int64) *datastore.Key {
	return datastore.NewKey(*c, "Category", "", id, nil)
}

func saveCategory(c *appengine.Context, category *Category) {
	key, err := datastore.Put(*c, createCategoryKey(c), category)
	panicIfErr(err)
	category.Id = key.IntID()
	if len(category.Code) == 0 {
		category.Code = translit(category.Name)
	}
	_, err = datastore.Put(*c, key, category)
	panicIfErr(err)
	return
}

func listAllCategories(c *appengine.Context) []*Category {
	categories := make([]*Category, 0)
	_, err := datastore.NewQuery("Category").GetAll(*c, &categories)
	panicIfErr(err)
	return categories
}

func updateCategory(c *appengine.Context, id int64, category *Category) {
	category.Id = id
	if len(category.Code) == 0 {
		category.Code = translit(category.Name)
	}
	_, err := datastore.Put(*c, restoreCategoryKey(c, id), category)
	panicIfErr(err)
}

func deleteCategory(c *appengine.Context, id int64) {
	// update dependent recipes
	recipes := make([]*Recipe, 0)
	datastore.NewQuery("Recipe").Filter("CategoryId =", id).GetAll(*c, &recipes)
	for i := 0; i < len(recipes); i++ {
		recipe := recipes[i]
		recipe.CategoryId = 0
		updateRecipe(c, recipe.Id, recipe)
	}
	err := datastore.Delete(*c, restoreCategoryKey(c, id))
	panicIfErr(err)
}

func getCategory(c *appengine.Context, id int64) *Category {
	category := new(Category)
	err := datastore.Get(*c, restoreCategoryKey(c, id), category)
	panicIfErr(err)
	return category
}

func getCategoryByCode(c *appengine.Context, code string) *Category {
	categories := make([]*Category, 0, 1)
	_, err := datastore.NewQuery("Category").Filter("Code =", code).Limit(1).GetAll(*c, &categories)
	panicIfErr(err)
	return categories[0]
}